import multiprocessing
import traceback

from .common_func.print_logger import PrintLogger


class ErrorLogger:
    _logger = dict()

    @classmethod
    def add_logger(cls, subject_name: str, logger):
        cls._logger[subject_name] = logger

    @classmethod
    def get_logger(cls, subject_name: str):
        return cls._logger.get(subject_name, PrintLogger)


def exception_capture_decorator(_return=None, _exception=Exception, logger_name=None, extra_msg=""):
    """
    错误捕获装饰器
    用法：
        logger = get_basic_logger("test")

        @exception_capture_decorator(logger_name="logger", _exception=ImportError)
        def test_func(count):
            import NotExistModule
            return None

        res = test_func(100000)
    结果：
        [2023-08-17 20:14:51] [ERROR] Error occur when run [func:test_func], error msg: No module named 'NotExistModule'
    :param logger_name:
    :param _exception: 需要捕获的错误
    :param _return: 捕获到错误后返回结果
    :param extra_msg: 额外打印的信息
    :return:
    """
    if not logger_name:
        cur_process = multiprocessing.current_process()
        logger_name = cur_process.name
    _logger = ErrorLogger.get_logger(logger_name)

    def decorator(func):
        def wrapper(*args, **kwargs):
            try:
                result = func(*args, **kwargs)
            except _exception as e:
                error_msg = ''.join(traceback.format_exception(None, value=e, tb=e.__traceback__))
                _logger.error(f"Error occur when run [func:{func.__name__}] "
                              f"with arg:{args}, kwargs:{kwargs}, "
                              f"error msg: {error_msg}, extra msg: {extra_msg}")
                result = _return
            return result

        return wrapper

    return decorator


def capt_exc(_return=None, _exception=Exception, logger_name=None, extra_msg=""):
    """
    错误捕获装饰器, 用于替换 exception_capture_decorator， 增加错误信息返回
    如果_return = "FalseErrorMsg"
        出错时 返回： (False, 'extra_msg, e')
    用法：
        logger = get_basic_logger("test")

        @capt_exc(logger_name="logger", _exception=ImportError)
        def test_func(count):
            import NotExistModule
            return None

        res = test_func(100000)
    结果：
        [2023-08-17 20:14:51] [ERROR] Error occur when run [func:test_func], error msg: No module named 'NotExistModule'
    :param logger_name:
    :param _exception: 需要捕获的错误
    :param _return: 捕获到错误后返回结果
    :param extra_msg: 额外打印的信息
    :return:
    """

    def decorator(func):
        def wrapper(*args, **kwargs):
            _logger = ErrorLogger.get_logger(logger_name)
            try:
                result = func(*args, **kwargs)
            except _exception as e:
                error_msg = ''.join(traceback.format_exception(None, value=e, tb=e.__traceback__))
                _logger.error(f"Error occur when run [func:{func.__name__}] "
                              f"with arg:{args}, kwargs:{kwargs}, "
                              f"error msg: {error_msg}, extra msg: {extra_msg}")
                if _return == "FalseErrorMsg":
                    result = (False, f"{extra_msg} {e}")
                else:
                    result = _return
            return result

        return wrapper

    return decorator


class DatabaseException(Exception):
    pass


class DatabaseConfigError(DatabaseException):
    pass


class DatabaseConnectError(DatabaseException):
    pass


class RuntimeException(Exception):
    pass


class UpdateLogThreadException(RuntimeException):
    pass


class CommandFormatError(RuntimeException):
    pass


class FileException(Exception):
    pass


class FileNotFound(FileException):
    pass


class FileEmptyError(FileException):
    pass


class ConfigNotFound(FileException):
    pass


class DatabaseException(Exception):
    pass


class RuntimeException(Exception):
    pass



class FileException(Exception):
    pass


class AddCommandError(CommandFormatError):
    pass



class DatabaseError(Exception):
    def __init__(self,error_info):
        self.error_info=error_info

    def __str__(self):
        return self.error_info


class FileError(Exception):
    def __init__(self, error_info):
        self.error_info = error_info

    def __str__(self):
        return self.error_info

class ContentError(Exception):
    def __init__(self, error_info):
        self.error_info = error_info

    def __str__(self):
        return self.error_info

class ESError(Exception):
    def __init__(self, error_info):
        self.error_info = error_info

    def __str__(self):
        return self.error_info


class ArgIsNotHandlerError(Exception):
    def __init__(self):
        self.msg = "参数错误，不是日志处理器，无法处理!"

    def __str__(self):
        return self.msg


class ArgIsNotFormatterError(Exception):
    def __init__(self):
        self.msg = "参数错误，不是日志格式化器，无法处理!"

    def __str__(self):
        return self.msg


class ArgIsNotLoggerError(Exception):
    def __init__(self):
        self.msg = "参数错误，不是日志句柄，无法处理!"

    def __str__(self):
        return self.msg
